package cz.muni.fi.pv168.addressbook.gui;

import cz.muni.fi.pv168.addressbook.daos.impl.handler.ManagersHandler;
import cz.muni.fi.pv168.addressbook.entities.Contact;
import cz.muni.fi.pv168.addressbook.entities.ContactType;
import cz.muni.fi.pv168.addressbook.entities.Person;
import cz.muni.fi.pv168.addressbook.entities.validators.Validator;
import cz.muni.fi.pv168.addressbook.gui.components.ContactJButton;
import cz.muni.fi.pv168.addressbook.gui.utils.ContactTypeHandler;
import cz.muni.fi.pv168.addressbook.gui.utils.JOptionDialogWindowHandler;
import cz.muni.fi.pv168.addressbook.gui.utils.SwingWorkerOperationsEnum;
import cz.muni.fi.pv168.addressbook.utils.DateCreator;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;

import static cz.muni.fi.pv168.addressbook.gui.utils.JOptionDialogWindowHandler.showErrorDialogWindow;
import static cz.muni.fi.pv168.addressbook.gui.utils.JOptionDialogWindowHandler.showInfoDialogWindow;
import static cz.muni.fi.pv168.addressbook.gui.utils.SwingWorkerOperationsEnum.ADD_CONTACT_OPERATION;
import static cz.muni.fi.pv168.addressbook.gui.utils.SwingWorkerOperationsEnum.ADD_PERSON_OPERATION;
import static cz.muni.fi.pv168.addressbook.gui.utils.SwingWorkerOperationsEnum.CHANGE_CONTACT_OPERATION;
import static cz.muni.fi.pv168.addressbook.gui.utils.SwingWorkerOperationsEnum.CHANGE_PERSON_OPERATION;
import static cz.muni.fi.pv168.addressbook.gui.utils.SwingWorkerOperationsEnum.GET_PERSON_CONTACTS_OPERATION;
import static cz.muni.fi.pv168.addressbook.gui.utils.SwingWorkerOperationsEnum.REMOVE_CONTACT_OPERATION;
import static java.util.Collections.emptyList;
import static java.util.ResourceBundle.getBundle;
import static java.util.logging.Logger.getLogger;

/**
 *
 * @author Michal Ďuriš
 */
public class DetailDialogWindow extends javax.swing.JDialog {

    private static final long serialVersionUID = 1L;

    private Person person = null;

    private final List<ContactJButton> contactJButtonList = new ArrayList<>();

    private ManagersHandler managersHandler;

    private final MainWindow addressBookMainWindow;

    /**
     * Creates new form DetailDialogWindow
     *
     * @param parent
     * @param modal
     */
    public DetailDialogWindow(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();

        setLocationRelativeTo(parent);

        addressBookMainWindow = (MainWindow) parent;
    }

    public void runPersonDialogWindow(Person person,
                                      ManagersHandler managersHandler, int state) {

        if (state == MainWindow.ADD_PERSON_DIALOG) {

            this.managersHandler = managersHandler;

            makeCardPanelVisible("addPersonPanel");
            setVisible(true);

        } else if (state == MainWindow.DETAIL_PERSON_DIALOG) {

            if (person == null) {
                ResourceBundle bundle = getBundle(
                        MainWindow.BUNDLE_PATH);

                showErrorDialogWindow(this,
                        bundle.getString("ErrorMessage.Title"),
                        bundle.getString("ErrorMessage.noPerson"));

                getLogger(DetailDialogWindow.class.getName()).logp(
                        Level.SEVERE, getClass().getName(),
                        "runPersonDialogWindow", bundle.getString(
                                "ErrorMessage.noPerson"));
                dispose();
            }

            this.person = person;
            this.managersHandler = managersHandler;

            setPersonInfo();

            new DetailDialogWindowSwingWorker(
                    SwingWorkerOperationsEnum.GET_PERSON_CONTACTS_OPERATION)
                    .execute();

            setVisible(true);

        } else {

            ResourceBundle bundle = getBundle(
                    MainWindow.BUNDLE_PATH);

            showErrorDialogWindow(this,
                    bundle.getString("ErrorMessage.Title"),
                    bundle.getString("ErrorMessage.dialogStateError"));

            getLogger(DetailDialogWindow.class.getName()).logp(
                    Level.SEVERE, getClass().getName(),
                    "runPersonDialogWindow", bundle.getString(
                            "ErrorMessage.dialogStateError"));
            dispose();
        }
    }

    public boolean isDialogWindowOfPerson(Person person) {

        return Objects.equals(this.person, person);
    }

    private class DetailDialogWindowSwingWorker extends SwingWorker<List<Contact>, Void> {

        private SwingWorkerOperationsEnum operation;

        private Person personToStoreInDatabase = null;
        private Contact contactToStoreInDatabase = null;

        private Contact contactBeforeUpdate = null;

        private ContactJButton contactToRemoveFromDatabase = null;

        public DetailDialogWindowSwingWorker(SwingWorkerOperationsEnum operation) {
            this.operation = operation;
        }

        public void setOperation(SwingWorkerOperationsEnum operation) {
            this.operation = operation;
        }

        public void setPersonToStoreInDatabase(Person person) {
            personToStoreInDatabase = person;
        }

        public void setContactToStoreInDatabase(Contact contactToStoreInDatabase) {
            this.contactToStoreInDatabase = contactToStoreInDatabase;
        }

        public void setContactToStoreInDatabaseWithHistory(
                Contact currentContact, Contact newContact) {
            contactBeforeUpdate = currentContact;
            contactToStoreInDatabase = newContact;
        }

        public void setContactToRemoveFromDatabase(
                ContactJButton contactToRemoveFromDatabase) {
            this.contactToRemoveFromDatabase = contactToRemoveFromDatabase;
        }

        @Override
        protected List<Contact> doInBackground() throws Exception {

            switch (operation) {
                case ADD_PERSON_OPERATION:
                    managersHandler.createPerson(
                            personToStoreInDatabase);
                    break;
                case CHANGE_PERSON_OPERATION:
                    managersHandler.updatePerson(
                            personToStoreInDatabase);
                    break;
                case ADD_CONTACT_OPERATION:
                    managersHandler.addContactToPerson(
                            contactToStoreInDatabase);
                    break;
                case CHANGE_CONTACT_OPERATION:
                    managersHandler.updateContact(
                            contactToStoreInDatabase);
                    break;
                case REMOVE_CONTACT_OPERATION:
                    managersHandler.removeContactFromPerson(
                            contactToRemoveFromDatabase.getContact());
                    break;
                case GET_PERSON_CONTACTS_OPERATION:
                    return managersHandler.getAllContactsOfPerson(person);

                default:
                    throw new IllegalStateException(
                            "UNRECOGNIZED SWING WORKER OPERATION !!!");
            }

            return emptyList();
        }

        @Override
        protected void done() {

            ResourceBundle bundle = getBundle(
                    MainWindow.BUNDLE_PATH);

            try {
                String infoTitle = bundle.getString("InfoMessage.Title");

                List<Contact> contactList = get();

                switch (operation) {
                    case ADD_PERSON_OPERATION:
                        person = personToStoreInDatabase;
                        addressBookMainWindow.addPersonToPersonList(person);
                        makeCardPanelVisible("contactPanel");

                        showInfoDialogWindow(
                                DetailDialogWindow.this,
                                infoTitle, bundle.getString(
                                        "InfoMessage.addPerson"));
                        break;

                    case CHANGE_PERSON_OPERATION:
                        person.setFirstName(personToStoreInDatabase
                                .getFirstName());
                        person.setLastName(personToStoreInDatabase
                                        .getLastName());
                        person.setBirthDate(personToStoreInDatabase
                                .getBirthDate());
                        person.setNote(personToStoreInDatabase.getNote());

                        addressBookMainWindow.validate();
                        addressBookMainWindow.repaint();
                        
                        showInfoDialogWindow(
                                DetailDialogWindow.this,
                                infoTitle,
                                bundle.getString("InfoMessage.changePerson"));
                        
                        
                        dispose();
                        break;

                    case ADD_CONTACT_OPERATION:
                        addContactToContactList(contactToStoreInDatabase, bundle);
                        validate();
                        repaint();

                        showInfoDialogWindow(
                                DetailDialogWindow.this,
                                infoTitle,
                                bundle.getString("InfoMessage.addContact"));
                        break;

                    case CHANGE_CONTACT_OPERATION:
                        contactBeforeUpdate.setContactValue(
                                contactToStoreInDatabase.getContactValue());

                        showInfoDialogWindow(
                                DetailDialogWindow.this,
                                infoTitle,
                                bundle.getString("InfoMessage.changeContact"));
                        break;

                    case REMOVE_CONTACT_OPERATION:
                        removeContactFromContactList(contactToRemoveFromDatabase);

                        showInfoDialogWindow(
                                DetailDialogWindow.this,
                                infoTitle,
                                bundle.getString("InfoMessage.removeContact"));
                        validate();
                        repaint();
                        break;

                    case GET_PERSON_CONTACTS_OPERATION:
                        showPersonsContacts(contactList);
                        break;

                    default:
                        getLogger(DetailDialogWindow.class.getName())
                                .logp(Level.SEVERE,
                                        this.getClass().getName(),
                                        "done()",
                                        bundle.getString(
                                                "ErrorMessage.swingWorkerBadOperation"));

                        showErrorDialogWindow(
                                DetailDialogWindow.this,
                                bundle.getString("ErrorMessage.Title"),
                                bundle.getString(
                                        "ErrorMessage.swingWorkerBadOperation"));
                }
            } catch (InterruptedException | ExecutionException ex) {
                String errorMessage;

                switch (operation) {
                    case ADD_PERSON_OPERATION:
                        errorMessage = bundle
                                .getString("ErrorMessage.addPerson");
                        break;
                    case CHANGE_PERSON_OPERATION:
                        errorMessage = bundle.getString(
                                "ErrorMessage.changePerson");
                        break;
                    case ADD_CONTACT_OPERATION:
                        errorMessage = bundle.getString(
                                "ErrorMessage.addContact");
                        break;
                    case CHANGE_CONTACT_OPERATION:
                        errorMessage = bundle.getString(
                                "ErrorMessage.changeContact");
                        break;
                    case REMOVE_CONTACT_OPERATION:
                        errorMessage = bundle.getString(
                                "ErrorMessage.removeContact");
                        break;
                    case GET_PERSON_CONTACTS_OPERATION:
                        errorMessage = bundle.getString(
                                "ErrorMessage.loadContacts");
                        break;
                    default:
                        errorMessage = bundle.getString(
                                "ErrorMessage.swingWorkerBadOperation");
                }

                getLogger(DetailDialogWindow.class.getName()).log(
                        Level.SEVERE, errorMessage, ex);

                showErrorDialogWindow(
                        DetailDialogWindow.this, bundle.getString(
                                "ErrorMessage.Title"), errorMessage);
            }
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        personPanel = new javax.swing.JPanel();
        firstNameLabel = new javax.swing.JLabel();
        firstNameTextField = new javax.swing.JTextField();
        lastNameLabel = new javax.swing.JLabel();
        lastNameTextField = new javax.swing.JTextField();
        birthdayPanel = new javax.swing.JPanel();
        dayLabel = new javax.swing.JLabel();
        dayTextField = new javax.swing.JTextField();
        monthLabel = new javax.swing.JLabel();
        monthTextField = new javax.swing.JTextField();
        yearLabel = new javax.swing.JLabel();
        yearTextField = new javax.swing.JTextField();
        notePanel = new javax.swing.JPanel();
        noteScrollPane = new javax.swing.JScrollPane();
        noteTextArea = new javax.swing.JTextArea();
        choosePanelCardPanel = new javax.swing.JPanel();
        contactCardPanel = new javax.swing.JPanel();
        contactsPanel = new javax.swing.JPanel();
        addPhoneButton = new javax.swing.JButton();
        addEmailButton = new javax.swing.JButton();
        addAddressButton = new javax.swing.JButton();
        personContantsScrollPane = new javax.swing.JScrollPane();
        personContactsPanel = new javax.swing.JPanel();
        saveButton = new javax.swing.JButton();
        contactsCancelButton = new javax.swing.JButton();
        addPersonCardPanel = new javax.swing.JPanel();
        addButton = new javax.swing.JButton();
        addPersonCancelButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("cz/muni/fi/pv168/addressbook/resources/lang/Bundle"); // NOI18N
        setTitle(bundle.getString("DetailDialogWindow.title")); // NOI18N
        setIconImage(new javax.swing.ImageIcon(getClass().getResource("/cz/muni/fi/pv168/addressbook/resources/icons/window/Address-Book-icon.png")).getImage());

        personPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, bundle.getString("DetailDialogWindow.personPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 14), new java.awt.Color(0, 102, 255))); // NOI18N

        firstNameLabel.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        firstNameLabel.setForeground(new java.awt.Color(51, 153, 255));
        firstNameLabel.setText(bundle.getString("DetailDialogWindow.firstNameLabel.text")); // NOI18N
        firstNameLabel.setToolTipText(bundle.getString("DetailDialogWindow.firstNameLabel.toolTipText")); // NOI18N

        firstNameTextField.setColumns(30);
        firstNameTextField.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        firstNameTextField.setToolTipText(bundle.getString("DetailDialogWindow.firstNameTextField.toolTipText")); // NOI18N

        lastNameLabel.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        lastNameLabel.setForeground(new java.awt.Color(51, 153, 255));
        lastNameLabel.setText(bundle.getString("DetailDialogWindow.lastNameLabel.text")); // NOI18N
        lastNameLabel.setToolTipText(bundle.getString("DetailDialogWindow.lastNameLabel.toolTipText")); // NOI18N

        lastNameTextField.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        lastNameTextField.setToolTipText(bundle.getString("DetailDialogWindow.lastNameTextField.toolTipText")); // NOI18N

        birthdayPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, bundle.getString("DetailDialogWindow.birthdayPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 14), new java.awt.Color(51, 153, 255))); // NOI18N
        birthdayPanel.setToolTipText(bundle.getString("DetailDialogWindow.birthdayPanel.toolTipText")); // NOI18N

        dayLabel.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        dayLabel.setForeground(new java.awt.Color(51, 153, 255));
        dayLabel.setText(bundle.getString("DetailDialogWindow.dayLabel.text")); // NOI18N
        dayLabel.setToolTipText(bundle.getString("DetailDialogWindow.dayLabel.toolTipText")); // NOI18N

        dayTextField.setColumns(2);
        dayTextField.setToolTipText(bundle.getString("DetailDialogWindow.dayTextField.toolTipText")); // NOI18N

        monthLabel.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        monthLabel.setForeground(new java.awt.Color(51, 153, 255));
        monthLabel.setText(bundle.getString("DetailDialogWindow.monthLabel.text")); // NOI18N
        monthLabel.setToolTipText(bundle.getString("DetailDialogWindow.monthLabel.toolTipText")); // NOI18N

        monthTextField.setToolTipText(bundle.getString("DetailDialogWindow.monthTextField.toolTipText")); // NOI18N

        yearLabel.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        yearLabel.setForeground(new java.awt.Color(51, 153, 255));
        yearLabel.setText(bundle.getString("DetailDialogWindow.yearLabel.text")); // NOI18N
        yearLabel.setToolTipText(bundle.getString("DetailDialogWindow.yearLabel.toolTipText")); // NOI18N

        yearTextField.setToolTipText(bundle.getString("DetailDialogWindow.yearTextField.toolTipText")); // NOI18N

        javax.swing.GroupLayout birthdayPanelLayout = new javax.swing.GroupLayout(birthdayPanel);
        birthdayPanel.setLayout(birthdayPanelLayout);
        birthdayPanelLayout.setHorizontalGroup(
            birthdayPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(birthdayPanelLayout.createSequentialGroup()
                .addGap(18, 18, 18)
                .addComponent(dayLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(dayTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(monthLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(monthTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(yearLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(yearTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(71, Short.MAX_VALUE))
        );
        birthdayPanelLayout.setVerticalGroup(
            birthdayPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(birthdayPanelLayout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(birthdayPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(birthdayPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(yearLabel)
                        .addComponent(yearTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(birthdayPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(dayLabel)
                        .addComponent(dayTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(monthLabel)
                        .addComponent(monthTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
        );

        notePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, bundle.getString("DetailDialogWindow.notePanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 14), new java.awt.Color(51, 153, 255))); // NOI18N
        notePanel.setToolTipText(bundle.getString("DetailDialogWindow.notePanel.toolTipText")); // NOI18N

        noteTextArea.setColumns(20);
        noteTextArea.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        noteTextArea.setRows(2);
        noteTextArea.setToolTipText(bundle.getString("DetailDialogWindow.noteTextArea.toolTipText")); // NOI18N
        noteScrollPane.setViewportView(noteTextArea);

        javax.swing.GroupLayout notePanelLayout = new javax.swing.GroupLayout(notePanel);
        notePanel.setLayout(notePanelLayout);
        notePanelLayout.setHorizontalGroup(
            notePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(notePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(noteScrollPane)
                .addContainerGap())
        );
        notePanelLayout.setVerticalGroup(
            notePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(notePanelLayout.createSequentialGroup()
                .addComponent(noteScrollPane)
                .addContainerGap())
        );

        javax.swing.GroupLayout personPanelLayout = new javax.swing.GroupLayout(personPanel);
        personPanel.setLayout(personPanelLayout);
        personPanelLayout.setHorizontalGroup(
            personPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(personPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(personPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(firstNameLabel)
                    .addComponent(lastNameLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(personPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(firstNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE)
                    .addComponent(lastNameTextField))
                .addContainerGap())
            .addGroup(personPanelLayout.createSequentialGroup()
                .addGap(10, 10, 10)
                .addComponent(birthdayPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGap(10, 10, 10))
            .addGroup(personPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(notePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        personPanelLayout.setVerticalGroup(
            personPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(personPanelLayout.createSequentialGroup()
                .addGroup(personPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(firstNameLabel)
                    .addComponent(firstNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(personPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lastNameLabel)
                    .addComponent(lastNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(birthdayPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(notePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        choosePanelCardPanel.setPreferredSize(new java.awt.Dimension(350, 255));
        choosePanelCardPanel.setLayout(new java.awt.CardLayout());

        contactCardPanel.setName("contactPanel"); // NOI18N
        contactCardPanel.setPreferredSize(new java.awt.Dimension(350, 329));

        contactsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, bundle.getString("DetailDialogWindow.contactsPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 14), new java.awt.Color(0, 102, 255))); // NOI18N
        contactsPanel.setToolTipText(bundle.getString("DetailDialogWindow.contactsPanel.toolTipText")); // NOI18N
        contactsPanel.setPreferredSize(new java.awt.Dimension(350, 211));
        contactsPanel.setLayout(new java.awt.GridBagLayout());

        addPhoneButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/cz/muni/fi/pv168/addressbook/resources/icons/buttons/Mobile_phone_add_icon.png"))); // NOI18N
        addPhoneButton.setText(bundle.getString("DetailDialogWindow.addPhoneButton.text")); // NOI18N
        addPhoneButton.setToolTipText(bundle.getString("DetailDialogWindow.addPhoneButton.toolTipText")); // NOI18N
        addPhoneButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addPhoneButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.ipadx = -27;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(7, 7, 3, 0);
        contactsPanel.add(addPhoneButton, gridBagConstraints);

        addEmailButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/cz/muni/fi/pv168/addressbook/resources/icons/buttons/Mail-new-icon.png"))); // NOI18N
        addEmailButton.setToolTipText(bundle.getString("DetailDialogWindow.addEmailButton.toolTipText")); // NOI18N
        addEmailButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addEmailButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.ipadx = -27;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(7, 7, 3, 0);
        contactsPanel.add(addEmailButton, gridBagConstraints);

        addAddressButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/cz/muni/fi/pv168/addressbook/resources/icons/buttons/Home_add_icon.png"))); // NOI18N
        addAddressButton.setToolTipText(bundle.getString("DetailDialogWindow.addAddressButton.toolTipText")); // NOI18N
        addAddressButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addAddressButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.ipadx = -27;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(7, 7, 3, 0);
        contactsPanel.add(addAddressButton, gridBagConstraints);

        personContactsPanel.setLayout(new javax.swing.BoxLayout(personContactsPanel, javax.swing.BoxLayout.PAGE_AXIS));
        personContantsScrollPane.setViewportView(personContactsPanel);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.ipadx = 331;
        gridBagConstraints.ipady = 82;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(4, 7, 4, 7);
        contactsPanel.add(personContantsScrollPane, gridBagConstraints);

        saveButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
        saveButton.setForeground(new java.awt.Color(0, 102, 255));
        saveButton.setText(bundle.getString("DetailDialogWindow.saveButton.text")); // NOI18N
        saveButton.setToolTipText(bundle.getString("DetailDialogWindow.saveButton.toolTipText")); // NOI18N
        saveButton.setPreferredSize(new java.awt.Dimension(80, 24));
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });

        contactsCancelButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
        contactsCancelButton.setForeground(new java.awt.Color(0, 102, 255));
        contactsCancelButton.setText(bundle.getString("DetailDialogWindow.contactsCancelButton.text")); // NOI18N
        contactsCancelButton.setToolTipText(bundle.getString("DetailDialogWindow.contactsCancelButton.toolTipText")); // NOI18N
        contactsCancelButton.setPreferredSize(new java.awt.Dimension(80, 24));
        contactsCancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                contactsCancelButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout contactCardPanelLayout = new javax.swing.GroupLayout(contactCardPanel);
        contactCardPanel.setLayout(contactCardPanelLayout);
        contactCardPanelLayout.setHorizontalGroup(
            contactCardPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(contactCardPanelLayout.createSequentialGroup()
                .addComponent(contactsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, contactCardPanelLayout.createSequentialGroup()
                .addGap(0, 0, Short.MAX_VALUE)
                .addComponent(saveButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(26, 26, 26)
                .addComponent(contactsCancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(24, 24, 24))
        );
        contactCardPanelLayout.setVerticalGroup(
            contactCardPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(contactCardPanelLayout.createSequentialGroup()
                .addComponent(contactsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(contactCardPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(saveButton, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(contactsCancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        choosePanelCardPanel.add(contactCardPanel, "contactPanel");

        addPersonCardPanel.setName("addPersonPanel"); // NOI18N

        addButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
        addButton.setForeground(new java.awt.Color(0, 102, 255));
        addButton.setText(bundle.getString("DetailDialogWindow.addButton.text")); // NOI18N
        addButton.setToolTipText(bundle.getString("DetailDialogWindow.addButton.toolTipText")); // NOI18N
        addButton.setPreferredSize(new java.awt.Dimension(80, 24));
        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addButtonActionPerformed(evt);
            }
        });

        addPersonCancelButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
        addPersonCancelButton.setForeground(new java.awt.Color(0, 102, 255));
        addPersonCancelButton.setText(bundle.getString("DetailDialogWindow.addPersonCancelButton.text")); // NOI18N
        addPersonCancelButton.setToolTipText(bundle.getString("DetailDialogWindow.addPersonCancelButton.toolTipText")); // NOI18N
        addPersonCancelButton.setPreferredSize(new java.awt.Dimension(80, 24));
        addPersonCancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addPersonCancelButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout addPersonCardPanelLayout = new javax.swing.GroupLayout(addPersonCardPanel);
        addPersonCardPanel.setLayout(addPersonCardPanelLayout);
        addPersonCardPanelLayout.setHorizontalGroup(
            addPersonCardPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(addPersonCardPanelLayout.createSequentialGroup()
                .addContainerGap(202, Short.MAX_VALUE)
                .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(addPersonCancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(20, 20, 20))
        );
        addPersonCardPanelLayout.setVerticalGroup(
            addPersonCardPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, addPersonCardPanelLayout.createSequentialGroup()
                .addContainerGap(219, Short.MAX_VALUE)
                .addGroup(addPersonCardPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(addPersonCancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        choosePanelCardPanel.add(addPersonCardPanel, "addPersonPanel");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(personPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(choosePanelCardPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(personPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(choosePanelCardPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 254, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void contactsCancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_contactsCancelButtonActionPerformed
        dispose();
    }//GEN-LAST:event_contactsCancelButtonActionPerformed

    private void addPersonCancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addPersonCancelButtonActionPerformed
        dispose();
    }//GEN-LAST:event_addPersonCancelButtonActionPerformed

    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
        changePersonInPersonsList();
    }//GEN-LAST:event_saveButtonActionPerformed

    private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
        addPersonToPersonsList();
    }//GEN-LAST:event_addButtonActionPerformed

    private void addPhoneButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addPhoneButtonActionPerformed
        showInputDialogToCreateContact(ContactType.PHONE);
    }//GEN-LAST:event_addPhoneButtonActionPerformed

    private void addEmailButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addEmailButtonActionPerformed
        showInputDialogToCreateContact(ContactType.EMAIL);
    }//GEN-LAST:event_addEmailButtonActionPerformed

    private void addAddressButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addAddressButtonActionPerformed
        showInputDialogToCreateContact(ContactType.ADDRESS);
    }//GEN-LAST:event_addAddressButtonActionPerformed

    private void addPersonToPersonsList() {
        Person newPerson = getAndValidatePersonInfo();

        if (newPerson != null) {
            DetailDialogWindowSwingWorker dialogSwingWorker = new DetailDialogWindowSwingWorker(
                    SwingWorkerOperationsEnum.ADD_PERSON_OPERATION);
            dialogSwingWorker.setPersonToStoreInDatabase(newPerson);
            dialogSwingWorker.execute();
        }
    }

    private void changePersonInPersonsList() {
        Person newPerson = getAndValidatePersonInfo();

        if (newPerson != null) {
            newPerson.setId(person.getId());

            DetailDialogWindowSwingWorker dialogSwingWorker = new DetailDialogWindowSwingWorker(
                    SwingWorkerOperationsEnum.CHANGE_PERSON_OPERATION);
            dialogSwingWorker.setPersonToStoreInDatabase(newPerson);
            dialogSwingWorker.execute();
        }
    }

    private void makeCardPanelVisible(String cardPanelName) {
        CardLayout cardLayout = (CardLayout) choosePanelCardPanel.getLayout();
        cardLayout.show(choosePanelCardPanel, cardPanelName);
    }

    private Person getAndValidatePersonInfo() {
        Person newPerson = null;
        List<String> errorList = new ArrayList<>();
        ResourceBundle bundle = ResourceBundle.getBundle(MainWindow.BUNDLE_PATH);

        restorePreviousForegroundColorInInputLabels(bundle);

        LocalDate birthDate = null;

        String firstName = firstNameTextField.getText();
        String lastName = lastNameTextField.getText();

        String birthDay = dayTextField.getText();
        String birthMonth = monthTextField.getText();
        String birthYear = yearTextField.getText();

        String note = noteTextArea.getText();

        if (!Validator.NOT_EMPTY_STRING_PREDICATE.test(lastName)) {

            errorList.add("lastname");
        }

        if ((Validator.NOT_EMPTY_STRING_PREDICATE.test(birthDay))
            && (Validator.NOT_EMPTY_STRING_PREDICATE.test(birthMonth))
            && (Validator.NOT_EMPTY_STRING_PREDICATE.test(birthYear))) {

            birthDate = DateCreator.validateAndCreateDate(birthDay, birthMonth,
                    birthYear, errorList);

        } else {
            dayTextField.setText("");
            monthTextField.setText("");
            yearTextField.setText("");
        }

        if (!errorList.isEmpty()) {
            StringBuilder errorMessage = new StringBuilder();

            if (errorList.contains("lastname")) {

                lastNameLabel.setForeground(Color.RED);
                errorMessage.append(bundle.getString("ErrorMessage.noLastname"))
                        .append(" \n");
            }

            if (errorList.contains("day")) {

                dayLabel.setForeground(Color.red);
                errorMessage.append(bundle.getString("ErrorMessage.badDay"))
                        .append(" \n");
            }

            if (errorList.contains("month")) {

                monthLabel.setForeground(Color.red);
                errorMessage.append(bundle.getString("ErrorMessage.badMonth"))
                        .append(" \n");
            }

            if (errorList.contains("year")) {

                yearLabel.setForeground(Color.red);
                errorMessage.append(bundle.getString("ErrorMessage.badYear"))
                        .append(" \n");
            }

            if (errorList.contains("date")) {

                birthdayPanel.setBorder(javax.swing.BorderFactory
                        .createTitledBorder(null, bundle.getString(
                                        "DetailDialogWindow.birthdayPanel.border.title"),
                                javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
                                javax.swing.border.TitledBorder.DEFAULT_POSITION,
                                new java.awt.Font("Tahoma", 1, 14), Color.RED)); // NOI18N

                errorMessage.append(bundle
                        .getString("ErrorMessage.badBirthdate")).append(" \n");
            }

            JOptionDialogWindowHandler.showErrorDialogWindow(this, bundle
                    .getString("ErrorMessage.Title"), errorMessage.toString());
        } else {

            newPerson = new Person(firstName, lastName, note, birthDate);
        }

        return newPerson;
    }

    private void setPersonInfo() {

        firstNameTextField.setText(person.getFirstName());
        lastNameTextField.setText(person.getLastName());

        if (person.getBirthDate() != null) {
            setPersonBirthdate(person.getBirthDate());
        }

        noteTextArea.setText(person.getNote());
    }

    private void setPersonBirthdate(LocalDate birthdate) {

        dayTextField.setText(String.valueOf(birthdate.getDayOfMonth()));

        monthTextField.setText(String.valueOf(birthdate.getMonthValue()));

        yearTextField.setText(String.valueOf(birthdate.getYear()));
    }

    public void changeLanguageInApplication() {

        ResourceBundle bundle = ResourceBundle.getBundle(MainWindow.BUNDLE_PATH);

        setTitle(bundle.getString("DetailDialogWindow.title")); // NOI18N
        personPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null,
                bundle.getString("DetailDialogWindow.personPanel.border.title"),
                javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
                javax.swing.border.TitledBorder.DEFAULT_POSITION,
                new java.awt.Font("Tahoma", 1, 14), new java.awt.Color(0, 102,
                        255))); // NOI18N
        lastNameTextField.setToolTipText(bundle.getString(
                "DetailDialogWindow.lastNameTextField.toolTipText")); // NOI18N
        addPhoneButton.setText(bundle.getString(
                "DetailDialogWindow.addPhoneButton.text")); // NOI18N
        firstNameLabel.setText(bundle.getString(
                "DetailDialogWindow.firstNameLabel.text")); // NOI18N
        notePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null,
                bundle.getString("DetailDialogWindow.notePanel.border.title"),
                javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
                javax.swing.border.TitledBorder.DEFAULT_POSITION,
                new java.awt.Font("Tahoma", 1, 14), new java.awt.Color(51, 153,
                        255))); // NOI18N
        notePanel.setToolTipText(bundle.getString(
                "DetailDialogWindow.notePanel.toolTipText")); // NOI18N
        firstNameTextField.setToolTipText(bundle.getString(
                "DetailDialogWindow.firstNameTextField.toolTipText")); // NOI18N
        monthLabel.setToolTipText(bundle.getString(
                "DetailDialogWindow.monthLabel.toolTipText")); // NOI18N
        dayTextField.setToolTipText(bundle.getString(
                "DetailDialogWindow.dayTextField.toolTipText")); // NOI18N
        addEmailButton.setToolTipText(bundle.getString(
                "DetailDialogWindow.addEmailButton.toolTipText")); // NOI18N
        birthdayPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(
                null, bundle.getString(
                        "DetailDialogWindow.birthdayPanel.border.title"),
                javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
                javax.swing.border.TitledBorder.DEFAULT_POSITION,
                new java.awt.Font("Tahoma", 1, 14), new java.awt.Color(51, 153,
                        255))); // NOI18N
        birthdayPanel.setToolTipText(bundle.getString(
                "DetailDialogWindow.birthdayPanel.toolTipText")); // NOI18N
        yearLabel.setText(bundle.getString("DetailDialogWindow.yearLabel.text")); // NOI18N
        firstNameLabel.setToolTipText(bundle.getString(
                "DetailDialogWindow.firstNameLabel.toolTipText")); // NOI18N
        lastNameLabel.setToolTipText(bundle.getString(
                "DetailDialogWindow.lastNameLabel.toolTipText")); // NOI18N
        dayLabel.setText(bundle.getString("DetailDialogWindow.dayLabel.text")); // NOI18N
        monthLabel.setText(bundle
                .getString("DetailDialogWindow.monthLabel.text")); // NOI18N
        yearLabel.setToolTipText(bundle.getString(
                "DetailDialogWindow.yearLabel.toolTipText")); // NOI18N
        noteTextArea.setToolTipText(bundle.getString(
                "DetailDialogWindow.noteTextArea.toolTipText")); // NOI18N
        addPhoneButton.setToolTipText(bundle.getString(
                "DetailDialogWindow.addPhoneButton.toolTipText")); // NOI18N
        contactsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(
                null, bundle.getString(
                        "DetailDialogWindow.contactsPanel.border.title"),
                javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
                javax.swing.border.TitledBorder.DEFAULT_POSITION,
                new java.awt.Font("Tahoma", 1, 14), new java.awt.Color(0, 102,
                        255))); // NOI18N
        contactsPanel.setToolTipText(bundle.getString(
                "DetailDialogWindow.contactsPanel.toolTipText")); // NOI18N
        dayLabel.setToolTipText(bundle.getString(
                "DetailDialogWindow.dayLabel.toolTipText")); // NOI18N
        monthTextField.setToolTipText(bundle.getString(
                "DetailDialogWindow.monthTextField.toolTipText")); // NOI18N
        addAddressButton.setToolTipText(bundle.getString(
                "DetailDialogWindow.addAddressButton.toolTipText")); // NOI18N
        yearTextField.setToolTipText(bundle.getString(
                "DetailDialogWindow.yearTextField.toolTipText")); // NOI18N
        lastNameLabel.setText(bundle.getString(
                "DetailDialogWindow.lastNameLabel.text")); // NOI18N

        setLanguageToContactButtons(bundle);

        saveButton.setText(bundle
                .getString("DetailDialogWindow.saveButton.text")); // NOI18N
        saveButton.setToolTipText(bundle.getString(
                "DetailDialogWindow.saveButton.toolTipText")); // NOI18N
        contactsCancelButton.setText(bundle.getString(
                "DetailDialogWindow.contactsCancelButton.text")); // NOI18N
        contactsCancelButton.setToolTipText(bundle.getString(
                "DetailDialogWindow.contactsCancelButton.toolTipText")); // NOI18N
        addButton.setText(bundle.getString("DetailDialogWindow.addButton.text")); // NOI18N
        addButton.setToolTipText(bundle.getString(
                "DetailDialogWindow.addButton.toolTipText")); // NOI18N
        addPersonCancelButton.setText(bundle.getString(
                "DetailDialogWindow.addPersonCancelButton.text")); // NOI18N
        addPersonCancelButton.setToolTipText(bundle.getString(
                "DetailDialogWindow.addPersonCancelButton.toolTipText")); // NOI18N
    }

    private void setLanguageToContactButtons(ResourceBundle bundle) {

        for (ContactJButton contactJButton : contactJButtonList) {
            contactJButton.setContactToolTipText(bundle);
        }
    }

    private void showPersonsContacts(List<Contact> contactList) {
        ResourceBundle bundle = ResourceBundle.getBundle(MainWindow.BUNDLE_PATH);

        contactList.stream()
                .forEach((contact) -> {
                    addContactToContactList(contact, bundle);
                });

        validate();
    }

    private void showInputDialogToCreateContact(ContactType contactType) {

        ResourceBundle bundle = ResourceBundle.getBundle(MainWindow.BUNDLE_PATH);
        String contactValue = null;

        try {

            contactValue = JOptionDialogWindowHandler
                    .showInputDialogWindow(this, bundle.getString(
                                    ContactTypeHandler
                                    .getContactTypeInternationalizedTitle(
                                            contactType)), bundle.getString(
                                    ContactTypeHandler
                                    .getContactTypeInternationalizedText(
                                            contactType)), null,
                            ContactTypeHandler.getContactTypImageIcon(
                                    contactType));

        } catch (IllegalStateException ex) {

            Logger.getLogger(DetailDialogWindow.class.getName()).log(
                    Level.SEVERE,
                    bundle.getString("ErrorMessage.badContactType"), ex);

            JOptionDialogWindowHandler.showErrorDialogWindow(this, bundle
                    .getString("ErrorMessage.Title"), bundle.getString(
                            "ErrorMessage.badContactType"));
        }

        if (Validator.NOT_EMPTY_STRING_PREDICATE.test(contactValue)) {
            if (contactValue.length() <= 50) {

                DetailDialogWindowSwingWorker dialogWindowSwingWorker = new DetailDialogWindowSwingWorker(
                        SwingWorkerOperationsEnum.ADD_CONTACT_OPERATION);

                dialogWindowSwingWorker.setContactToStoreInDatabase(new Contact(
                        person, contactType, contactValue));

                dialogWindowSwingWorker.execute();

            } else {

                JOptionDialogWindowHandler.showErrorDialogWindow(this,
                        bundle.getString("ErrorMessage.Title"),
                        bundle.getString("ErrorMessage.stringToLong"));

            }
        }

    }

    private void showInputDialogToChangeContact(Contact contact) {

        ResourceBundle bundle = ResourceBundle.getBundle(MainWindow.BUNDLE_PATH);
        String contactValue = null;

        try {
            contactValue = JOptionDialogWindowHandler
                    .showInputDialogWindow(this, bundle.getString(
                                    ContactTypeHandler
                                    .getContactTypeInternationalizedTitle(
                                            contact.getContactType())), bundle
                            .getString(ContactTypeHandler
                                    .getContactTypeInternationalizedText(contact
                                            .getContactType())), contact
                            .getContactValue(), ContactTypeHandler
                            .getContactTypImageIcon(contact.getContactType()));

        } catch (IllegalStateException ex) {

            Logger.getLogger(DetailDialogWindow.class.getName()).log(
                    Level.SEVERE,
                    bundle.getString("ErrorMessage.badContactType"), ex);

            JOptionDialogWindowHandler.showErrorDialogWindow(this, bundle
                    .getString("ErrorMessage.Title"), bundle.getString(
                            "ErrorMessage.badContactType"));
        }

        if (Validator.NOT_EMPTY_STRING_PREDICATE.test(contactValue)) {

            if (contactValue.length() <= 50) {

                if (!contactValue.equals(contact.getContactValue())) {

                    Contact newContact = new Contact(person, contact
                            .getContactType(), contactValue);

                    newContact.setId(contact.getId());

                    DetailDialogWindowSwingWorker dialogWindowSwingWorker = new DetailDialogWindowSwingWorker(
                            SwingWorkerOperationsEnum.CHANGE_CONTACT_OPERATION);

                    dialogWindowSwingWorker
                            .setContactToStoreInDatabaseWithHistory(contact,
                                    newContact);

                    dialogWindowSwingWorker.execute();
                }

            } else {
                JOptionDialogWindowHandler.showErrorDialogWindow(this,
                        bundle.getString("ErrorMessage.Title"),
                        bundle.getString("ErrorMessage.stringToLong"));
            }
        }
    }

    private void showConfirmDialogToRemoveContact(ContactJButton contact) {

        ResourceBundle bundle = ResourceBundle.getBundle(MainWindow.BUNDLE_PATH);

        if (JOptionDialogWindowHandler.showYesNoDialogWindow(this,
                bundle.getString("OptionMessage.Title.remove"),
                bundle.getString("OptionMessage.Text.contactRemoveConfirm")) == JOptionPane.YES_OPTION) {

            DetailDialogWindowSwingWorker dialogWindowSwingWorker = new DetailDialogWindowSwingWorker(
                    SwingWorkerOperationsEnum.REMOVE_CONTACT_OPERATION);

            dialogWindowSwingWorker.setContactToRemoveFromDatabase(contact);
            dialogWindowSwingWorker.execute();
        }

    }

    private ContactJButton createContactButton(Contact contact,
                                               ResourceBundle bundle) {

        ContactJButton contactButton = new ContactJButton(contact);

        try {

            contactButton.setPredefinedSettingsWithInternationalization(bundle);
            contactButton.addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {

                    if (e.getButton() == MouseEvent.BUTTON1) {
                        showInputDialogToChangeContact(contact);
                    } else if (e.getButton() == MouseEvent.BUTTON3) {
                        showConfirmDialogToRemoveContact(contactButton);
                    }
                }

            });

        } catch (IllegalStateException ex) {

            JOptionDialogWindowHandler.showErrorDialogWindow(this,
                    bundle.getString("ErrorMessage.Title"),
                    bundle.getString("ErrorMessage.noContactInButton"));

            Logger.getLogger(DetailDialogWindow.class.getName()).log(
                    Level.SEVERE,
                    bundle.getString("ErrorMessage.noContactInButton"), ex);

            return null;
        }

        return contactButton;
    }

    private void addContactToContactList(Contact contact, ResourceBundle bundle) {

        ContactJButton contactButton = createContactButton(contact, bundle);

        if (contactButton != null) {
            personContactsPanel.add(contactButton);
            contactJButtonList.add(contactButton);
        }
    }

    private void removeContactFromContactList(ContactJButton contact) {
        personContactsPanel.remove(contact);
        contactJButtonList.remove(contact);
    }

    private void restorePreviousForegroundColorInInputLabels(
            ResourceBundle bundle) {

        lastNameLabel.setForeground(new java.awt.Color(51, 153, 255));
        dayLabel.setForeground(new java.awt.Color(51, 153, 255));
        monthLabel.setForeground(new java.awt.Color(51, 153, 255));
        yearLabel.setForeground(new java.awt.Color(51, 153, 255));

        birthdayPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(
                null, bundle.getString(
                        "DetailDialogWindow.birthdayPanel.border.title"),
                javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
                javax.swing.border.TitledBorder.DEFAULT_POSITION,
                new java.awt.Font("Tahoma", 1, 14), new java.awt.Color(51, 153,
                        255))); // NOI18N
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addAddressButton;
    private javax.swing.JButton addButton;
    private javax.swing.JButton addEmailButton;
    private javax.swing.JButton addPersonCancelButton;
    private javax.swing.JPanel addPersonCardPanel;
    private javax.swing.JButton addPhoneButton;
    private javax.swing.JPanel birthdayPanel;
    private javax.swing.JPanel choosePanelCardPanel;
    private javax.swing.JPanel contactCardPanel;
    private javax.swing.JButton contactsCancelButton;
    private javax.swing.JPanel contactsPanel;
    private javax.swing.JLabel dayLabel;
    private javax.swing.JTextField dayTextField;
    private javax.swing.JLabel firstNameLabel;
    private javax.swing.JTextField firstNameTextField;
    private javax.swing.JLabel lastNameLabel;
    private javax.swing.JTextField lastNameTextField;
    private javax.swing.JLabel monthLabel;
    private javax.swing.JTextField monthTextField;
    private javax.swing.JPanel notePanel;
    private javax.swing.JScrollPane noteScrollPane;
    private javax.swing.JTextArea noteTextArea;
    private javax.swing.JPanel personContactsPanel;
    private javax.swing.JScrollPane personContantsScrollPane;
    private javax.swing.JPanel personPanel;
    private javax.swing.JButton saveButton;
    private javax.swing.JLabel yearLabel;
    private javax.swing.JTextField yearTextField;
    // End of variables declaration//GEN-END:variables
}
